package com.lmf.spring5;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.util.List;


public class ParsingXML {
    public static void main(String[] args) throws Exception {
        /**
         * 获取某个类字节码文件的三种方法：
         *      (1) Class clazz = com.lmf.spring5.UserDaoImpl.class;
         *      (2) Class clazz = Class.forName("com.lmf.spring5.UserDaoImpl");
         *      (3) UserDaoImpl userDaoImpl = new UserDaoImpl();
         *         Class clazz = userDaoImpl.getClass();
         */
//        Class clazz=com.lmf.spring5.UserDaoImpl.class;
//        Class clazz = Class.forName("com.lmf.spring5.UserDaoImpl");
        UserDaoImpl userDaoImpl = new UserDaoImpl();
        Class clazz = userDaoImpl.getClass();
        Constructor constructor = clazz.getConstructor();
        UserDaoImpl userDao = (UserDaoImpl) constructor.newInstance();
        int add = userDao.add(35, 5);
        System.out.println(add);
    }

    /**
     * 案例：利用xml解析技术，解析spring配置文件，并通过反射获取相应的类对象
     *
     * @throws Exception
     */
    @Test
    public void test1() throws Exception {
        //先创建一个 SAXReader 对象，用于读取xml文件
        SAXReader reader = new SAXReader();
        //调用read方法，读取需要解析的xml文件，通过url路径，获取一个Document对象
        Document document = reader.read("src/com/lmf/spring5/test_2.xml");
        //可以通过输出看看有没有测试成功
//        System.out.println(document);

        //通过Document对象获取spring配置文件的根元素对象
        Element rootElement = document.getRootElement();
        //可以输出看看
//        System.out.println(rootElement.asXML());

        //再通过根元素调用elements方法，获取根元素下面所有的子元素集合
        List<Element> beans = rootElement.elements("bean");
        //可以遍历输出看看
//        for (Element bean : beans) {
//            System.out.println(bean);
//        }

        //获取spring配置文件中“UserDaoImpl”类的路径；即，根元素下面第一个子元素userDao的class属性值
        String value = beans.get(0).attributeValue("class");
        //再通过Class类的静态forName方法，加载UserDaoImpl类的字节码文件
        Class clazz = Class.forName(value);
        //UserDaoImpl类的字节码文件，再通过反射，获取它的构造函数的类，这里是无参构造函数类
        Constructor cons = clazz.getConstructor();
        //通过构造函数类，创建一个新的实例，并强制转换类型为UserDaoImpl类型
        UserDaoImpl userDao = (UserDaoImpl) cons.newInstance();
        //调用UserDaoImpl类的方法
        int add = userDao.add(35, 5);
        //输出结果测试
        System.out.println(add);
    }
}
